package com.ecjtu.stadiumre_servations.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ecjtu.stadiumre_servations.config.RabbitMQConfig;
import com.ecjtu.stadiumre_servations.config.TimeConflictChecker;
import com.ecjtu.stadiumre_servations.entity.domain.*;
import com.ecjtu.stadiumre_servations.entity.dto.GroupActivityDTO;
import com.ecjtu.stadiumre_servations.entity.dto.GroupActivityQueryDTO;
import com.ecjtu.stadiumre_servations.entity.vo.GroupActivityDetailsVo;
import com.ecjtu.stadiumre_servations.mapper.*;
import com.ecjtu.stadiumre_servations.response.Result;
import com.ecjtu.stadiumre_servations.response.ResultCodeEnum;
import com.ecjtu.stadiumre_servations.service.GroupActivityService;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class GroupActivityServiceImpl implements GroupActivityService {
    @Autowired
    private GroupActivityMapper groupActivityMapper;

    @Autowired
    private GroupRecordMapper groupRecordMapper;
    @Autowired
    private VenueMapper venueMapper;
    @Autowired
    private StudentMapper studentMapper;
    @Autowired
    private GroupMemberMapper groupMemberMapper;
    @Autowired
    private TimeConflictChecker timeConflictChecker;
    @Autowired
    private BookingMapper bookingMapper;
    @Resource
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private AlipayServiceImpl alipayService;
    @Resource
    private RedisTemplate<String, GroupActivity> redisTemplate;
    @Transactional
    @Override
    public Result createGroupActivity(String userId, GroupActivityDTO groupActivityDTO) {
        System.out.println(111);
        // 检查时间冲突
        boolean conflictResult = timeConflictChecker.checkTimeConflictById(userId);
        if (conflictResult) {
            return Result.fail("时间存在冲突");
        }

        // 1. 参数校验
        if (groupActivityDTO == null) {
            return Result.fail("活动信息不能为空");
        }

//        // 2. 检查活动名称是否已存在
//        LambdaQueryWrapper<GroupActivity> queryWrapper = Wrappers.<GroupActivity>lambdaQuery()
//                .eq(GroupActivity::getActivityName, groupActivityDTO.getActivityName());
//        GroupActivity existingActivity = groupActivityMapper.selectOne(queryWrapper);
//        if (existingActivity != null) {
//            return Result.fail("活动名称已存在");
//        }
        Venue venue = venueMapper.selectById(groupActivityDTO.getActivityVenueId());
        LocalDateTime currentTime = LocalDateTime.now(ZoneId.of("Asia/Shanghai"));
        // 3.2 检查预约时间是否合理（开始时间 < 结束时间 且 开始时间 > 当前时间 结束时间<闭馆时间 开始时间>开馆时间）
        if (groupActivityDTO.getActivityStartTime().isAfter(groupActivityDTO.getActivityEndTime()) ||
                groupActivityDTO.getActivityStartTime().isBefore(currentTime) ||
                groupActivityDTO.getActivityEndTime().toLocalTime().isAfter(venue.getVenueEndTime().toLocalTime()) ||
                groupActivityDTO.getActivityStartTime().toLocalTime().isBefore(venue.getVenueStartTime().toLocalTime())){
            return Result.fail("创建活动失败，预约时间不合理");
        }
        // 3.3 检查该同学在该时间段是否有其他预约
        LambdaQueryWrapper<Booking> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Booking::getStudentId, userId);
        List<Booking> bookingList = bookingMapper.selectList(lambdaQueryWrapper);
        for (Booking booking : bookingList) {
            if (
                    timeConflictChecker.timeRangeOverlap(groupActivityDTO.getActivityStartTime(), groupActivityDTO.getActivityEndTime(),
                            booking.getBookingStartTime(), booking.getBookingEndTime())
            ) {
                return Result.fail("创建活动失败，该同学在该时间段有其他预约");
            }
        }
        // 4.1 查询该场地是否已有预约
        LambdaQueryWrapper<Booking> bookingQuery = Wrappers.<Booking>lambdaQuery()
                .eq(Booking::getVenueId, groupActivityDTO.getActivityVenueId());
        List<Booking> existingBookings = bookingMapper.selectList(bookingQuery);
        // 4.2 检查是否与已有预约冲突
        for (Booking existing : existingBookings) {
            // 若场馆预约被取消，则跳过
            if (existing.getBookingStatus().equals("已取消")||existing.getBookingStatus().equals("已使用"))
                continue;
            // 新预约开始时间 < 已有预约结束时间 且 新预约结束时间 > 已有预约开始时间
            if (timeConflictChecker.timeRangeOverlap(groupActivityDTO.getActivityStartTime(), groupActivityDTO.getActivityEndTime(),
                    existing.getBookingStartTime(), existing.getBookingEndTime())) {
                return Result.fail("创建活动失败，该时间段内该场地已存在预约");
            }
        }
        // 3. 转换DTO到实体类
        GroupActivity groupActivity = new GroupActivity();
        BeanUtils.copyProperties(groupActivityDTO, groupActivity);

        // 4. 生成活动ID
        groupActivity.setActivityId(UUID.randomUUID().toString());

        // 5. 设置默认状态为"未开始"
        groupActivity.setActivityStatus("拼团中");

        // 6. 设置创建时间
        groupActivity.setCreateTime(LocalDateTime.now());

        // 7. 设置价格
//        if (venue == null) {
//            return Result.fail("所选场馆不存在");
//        }
        long hoursBetween = ChronoUnit.HOURS.between(
                groupActivityDTO.getActivityStartTime(),
                groupActivityDTO.getActivityEndTime()
        );
        double price = venue.getVenuePrice() * hoursBetween / groupActivityDTO.getGroupSize() * 0.80;
        groupActivity.setActivityPrice(price); // 保存价格到实体
//         插入数据库，此时活动状态为待支付
        int activityResult = groupActivityMapper.insert(groupActivity);
        System.out.println(groupActivity.getActivityId());
        if (activityResult <= 0) {
            throw new RuntimeException("活动创建失败");
        }

        // 准备支付宝支付参数
        Map<String, String> alipayParams = new HashMap<>();
//        alipayParams.put("userId",userId);
        alipayParams.put("out_trade_no", groupActivity.getActivityId()); // 使用活动ID作为外部交易号
        alipayParams.put("total_amount", String.format("%.2f", price)); // 支付金额
        alipayParams.put("order_name", venue.getVenueName() + "预约支付"); // 订单名称
        alipayParams.put("body", "场地预约：" +
                "开始时间=" + groupActivityDTO.getActivityStartTime() +
                ",结束时间=" + groupActivityDTO.getActivityEndTime()); // 订单描述
        // 9 为团长生成一条预约记录
        Booking booking = new Booking();
        System.out.println("创建活动");
        booking.setBookingId(groupActivity.getActivityId());
        booking.setStudentId(userId);
        booking.setVenueId(groupActivity.getActivityVenueId());
        booking.setBookingStartTime(groupActivityDTO.getActivityStartTime());
        booking.setBookingEndTime(groupActivityDTO.getActivityEndTime());
        booking.setBookingTotalPrice(groupActivity.getActivityPrice());
        booking.setBookingStatus("已支付");
        booking.setBookingType("拼团预约");
        booking.setCreateTime(LocalDateTime.now());
        int result1 = bookingMapper.insert(booking);
        //10 保存拼团记录
        GroupRecord groupRecord = new GroupRecord();
        groupRecord.setLeaderUserId(userId);
        groupRecord.setRecordId(UUID.randomUUID().toString());
        groupRecord.setActivityId(groupActivity.getActivityId());
        groupRecord.setLeaderUserId(userId);
        groupRecord.setCurrentSize(1);
        groupRecord.setTargetSize(groupActivityDTO.getGroupSize());
        groupRecord.setStartTime(groupActivityDTO.getActivityStartTime());
        groupRecord.setEndTime(groupActivityDTO.getActivityEndTime());
        groupRecord.setRecordStatus("拼团中");
        groupRecord.setRecordCreateTime(LocalDateTime.now());
        groupRecord.setUpdateTime(LocalDateTime.now());
        int recordResult = groupRecordMapper.insert(groupRecord);
        if (recordResult <= 0) {
            throw new RuntimeException("拼团记录创建失败");
        }
        // 11. 添加团长作为第一个成员
        GroupMember leader = new GroupMember();
        leader.setMemberId(UUID.randomUUID().toString());
        leader.setUserId(userId);
        leader.setGroupRecordId(groupRecord.getRecordId());
        leader.setUserId(groupRecord.getLeaderUserId());
        leader.setIsLeader("true");
        leader.setPayStatus("已支付"); // 确认业务需求：待支付/已支付
        leader.setJoinTime(LocalDateTime.now());
        int memberResult = groupMemberMapper.insert(leader);
        if (memberResult <= 0) {
            throw new RuntimeException("团长成员记录创建失败");
        }
        // 创建消息内容，包含活动ID
        Map<String, String> message = new HashMap<>();
        message.put("activityId", groupActivity.getActivityId());
        message.put("bookingId", booking.getBookingId());
        rabbitTemplate.convertAndSend(
                RabbitMQConfig.EXCHANGE_NAME,
                RabbitMQConfig.GROUP_ACTIVITY_DELAYED_ROUTING_KEY, // 发送到延迟队列
                message
        );
        try {
            // 调用支付宝支付接口生成支付表单
            String form = alipayService.toAlipay(alipayParams);
            // 发送支付请求到消息队列，等待支付结果通知
            rabbitTemplate.convertAndSend(RabbitMQConfig.EXCHANGE_NAME, RabbitMQConfig.PAYMENT_REQUEST_ROUTING_KEY, alipayParams);
            // 返回支付表单给前端，让用户进行支付
            return Result.ok().data("form", form);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.fail("调用支付宝支付失败");
        }
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result deleteGroupActivity(String activityId) {
        // 检查活动是否存在
        GroupActivity groupActivity = groupActivityMapper.selectById(activityId);
        if (groupActivity == null) {
            return Result.fail("活动不存在");
        }
        LambdaQueryWrapper<GroupRecord> groupRecordQueryWrapper = new LambdaQueryWrapper<>();
        groupRecordQueryWrapper.eq(GroupRecord::getActivityId, activityId);
        GroupRecord groupRecord = groupRecordMapper.selectOne(groupRecordQueryWrapper);
        if (groupRecord.getRecordStatus().equals("已成图")){
            return Result.fail("拼团已成功,无法解散");
        }
        if (groupRecord.getRecordStatus().equals("拼团失败")){
            return Result.fail("拼团失败,无法操作");
        }
        // 删除活动对应的 groupRecord 记录
        groupRecordMapper.delete(groupRecordQueryWrapper);
        // 获取与活动相关的所有 groupRecord 的 ID
        LambdaQueryWrapper<GroupRecord> recordIdQueryWrapper = new LambdaQueryWrapper<>();
        recordIdQueryWrapper.select(GroupRecord::getRecordId).eq(GroupRecord::getActivityId, activityId);
        List<Object> groupRecordIds = groupRecordMapper.selectObjs(recordIdQueryWrapper);

        // 删除活动对应的 groupMember 记录
        if (!groupRecordIds.isEmpty()) {
            LambdaQueryWrapper<GroupMember> groupMemberQueryWrapper = new LambdaQueryWrapper<>();
            groupMemberQueryWrapper.in(GroupMember::getGroupRecordId, groupRecordIds);
            groupMemberMapper.delete(groupMemberQueryWrapper);
        }
        // 删除活动发起人的预约记录
        LambdaQueryWrapper<GroupRecord> leaderRecordQueryWrapper = new LambdaQueryWrapper<>();
        leaderRecordQueryWrapper.select(GroupRecord::getLeaderUserId).eq(GroupRecord::getActivityId, activityId);
        List<Object> leaderUserIds = groupRecordMapper.selectObjs(leaderRecordQueryWrapper);
        if (!leaderUserIds.isEmpty()) {
            LambdaQueryWrapper<Booking> bookingQueryWrapper = new LambdaQueryWrapper<>();
            bookingQueryWrapper.in(Booking::getStudentId, leaderUserIds);
            bookingMapper.delete(bookingQueryWrapper);
        }
        // 删除活动记录
        int success = groupActivityMapper.deleteById(activityId);
        if (success>0) {
            return Result.ok("活动删除成功");
        } else {
            return Result.fail("活动删除失败");
        }
    }
    /**
     * 根据ID查询拼团活动详情
     */
    @Override
    public Result getGroupActivityById(String activityId) {
//        String key = "groupActivity:" + activityId;
//        GroupActivity activity = redisTemplate.opsForValue().get(key);
//        if (activity == null) {
//            activity = groupActivityMapper.selectById(activityId);
//            if (activity != null) {
//                redisTemplate.opsForValue().set(key, activity, 60, TimeUnit.MINUTES);
//            }
//        }
        if (activityId == null) {
            return Result.fail("活动不存在");
        }
        GroupActivity activity = groupActivityMapper.selectById(activityId);
        LambdaQueryWrapper<GroupRecord> groupRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
        groupRecordLambdaQueryWrapper.eq(GroupRecord::getActivityId,activityId);
        GroupRecord groupRecord = groupRecordMapper.selectOne(groupRecordLambdaQueryWrapper);
        Venue venue = venueMapper.selectById(activity.getActivityVenueId());
        Student student = studentMapper.selectById(groupRecord.getLeaderUserId());
        GroupActivityDetailsVo groupActivityDetailsVo = new GroupActivityDetailsVo();
        // 用vo封装展示数据
        groupActivityDetailsVo.setVenueName(venue.getVenueName()+venue.getVenueNumber()); // 场馆名称
        groupActivityDetailsVo.setLeaderUserName(student.getName()); // 发起人姓名
//      groupActivityDetailsVo.setLeaderUserName(student.getStudentId()); // 发起人id
        groupActivityDetailsVo.setGroupActivityTotalPrice(activity.getActivityPrice()); // 参与拼团价格
        groupActivityDetailsVo.setTargetSize(activity.getGroupSize()); // 成团人数
        groupActivityDetailsVo.setActivityStartTime(activity.getActivityStartTime()); //开始时间
        groupActivityDetailsVo.setActivityEndTime(activity.getActivityEndTime()); // 结束时间
        groupActivityDetailsVo.setCreateTime(activity.getCreateTime()); //创建时间
        groupActivityDetailsVo.setCurrentSize(groupRecord.getCurrentSize()); // 当前人数
        groupActivityDetailsVo.setActivityStatus(groupRecord.getRecordStatus()); // 拼团状态
        LambdaQueryWrapper<GroupMember> groupMemberLambdaQueryWrapper = new LambdaQueryWrapper<>();
        groupMemberLambdaQueryWrapper.eq(GroupMember::getGroupRecordId,groupRecord. getRecordId());
        List<GroupMember> groupMemberList = groupMemberMapper.selectList(groupMemberLambdaQueryWrapper);
        List<String> studenNametList = new ArrayList<>();
        for (GroupMember g:groupMemberList){
            String studentName = studentMapper.selectById(g.getUserId()).getName();
            System.out.println(studentName);
            studenNametList.add(studentName);
        } // 参与人姓名列表

        groupActivityDetailsVo.setStudentNameList(studenNametList);
        groupActivityDetailsVo.setGroupMemberList(groupMemberList);
        groupActivityDetailsVo.setGroupRecordId(groupRecord.getRecordId());
        return Result.build(groupActivityDetailsVo, ResultCodeEnum.SELECT_SUCCESS);
    }

    @Override
    public Result getGroupActivityByActivityId(Page<GroupActivity> page, String activityId) {
        LambdaQueryWrapper<GroupActivity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.like(GroupActivity::getActivityId, activityId);
        Page<GroupActivity> groupActivityPage = groupActivityMapper.selectPage(page, lambdaQueryWrapper);
        if (groupActivityPage == null) {
            return Result.fail("不存在预约id为" + activityId + "的拼团活动");
        }
        return Result.ok(groupActivityPage);
    }

    @Override
    public Result getGroupActivityByUserId(String userId) {
            // 1. 查询用户参与的所有拼团成员记录
            LambdaQueryWrapper<GroupMember> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(GroupMember::getUserId, userId);
            List<GroupMember> groupMemberList = groupMemberMapper.selectList(queryWrapper);
            // 2. 提取所有拼团记录ID
            List<String> groupRecordIds = groupMemberList.stream()
                    .map(GroupMember::getGroupRecordId)
                    .collect(Collectors.toList());
            // 3. 批量查询所有拼团记录
            LambdaQueryWrapper<GroupRecord> recordQueryWrapper = new LambdaQueryWrapper<>();
            recordQueryWrapper.in(GroupRecord::getRecordId, groupRecordIds);
            if (groupRecordIds.isEmpty()){
                return Result.ok("该用户不存在拼团记录");
            }
            List<GroupRecord> groupRecordList = groupRecordMapper.selectList(recordQueryWrapper);
            // 4. 提取所有活动ID
            List<String> activityIds = groupRecordList.stream()
                    .map(GroupRecord::getActivityId)
                    .collect(Collectors.toList());
            if (activityIds.isEmpty()){
                return Result.ok("该用户不存在拼团记录");
            }
            // 5. 批量查询所有活动信息
            LambdaQueryWrapper<GroupActivity> activityQueryWrapper = new LambdaQueryWrapper<>();
            activityQueryWrapper.in(GroupActivity::getActivityId, activityIds);
            List<GroupActivity> groupActivityList = groupActivityMapper.selectList(activityQueryWrapper);
            return Result.ok(groupActivityList);
        }

    /**
     * 分页查询拼团活动列表
     */
    @Override
    public Result listGroupActivities(Page<GroupActivity> page, GroupActivityQueryDTO query) {
        // 执行查询
        return Result.build(groupActivityMapper.selectPage(page,null), ResultCodeEnum.SELECT_SUCCESS);

    }
    @Override
    public Result listGroupActivitiesByVenueId(Page<GroupActivity> page, String venueId) {
        LambdaQueryWrapper<GroupActivity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(GroupActivity::getActivityVenueId,venueId)
                .eq(GroupActivity::getActivityStatus,"拼团中");
        // 执行查询
        return Result.build(groupActivityMapper.selectPage(page,lambdaQueryWrapper), ResultCodeEnum.SELECT_SUCCESS);
    }
    /**
     * 构建查询条件
     */
    private LambdaQueryWrapper<GroupActivity> buildQueryWrapper(GroupActivityQueryDTO query) {
        // 参数检查，避免空指针异常
        if (query == null) {
            return Wrappers.lambdaQuery();
        }

        LambdaQueryWrapper<GroupActivity> wrapper = Wrappers.<GroupActivity>lambdaQuery();
        wrapper.eq(GroupActivity::getActivityStatus,"拼团中");
        // 按活动名称模糊查询
        if (StringUtils.isNotBlank(query.getActivityName())) {
            wrapper.like(GroupActivity::getActivityName, query.getActivityName());
        }

        // 按活动状态查询
        if (query.getActivityStatus() != null) {
            wrapper.eq(GroupActivity::getActivityStatus, query.getActivityStatus());
        }

        // 按时间范围查询 - 合并条件判断
        LocalDateTime startTime = query.getActivityStartTime();
        LocalDateTime endTime = query.getActivityEndTime();

        if (startTime != null && endTime != null) {
            // 开始时间和结束时间都存在，查询两者之间的记录
            wrapper.between(GroupActivity::getActivityStartTime, startTime, endTime);
        } else if (startTime != null) {
            // 只有开始时间，查询大于等于开始时间的记录
            wrapper.ge(GroupActivity::getActivityStartTime, startTime);
        } else if (endTime != null) {
            // 只有结束时间，查询小于等于结束时间的记录
            wrapper.le(GroupActivity::getActivityEndTime, endTime);
        }
        // 默认按创建时间降序排列
        wrapper.orderByDesc(GroupActivity::getCreateTime);
        return wrapper;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result updateGroupActivity(GroupActivity groupActivity) {
        // 1. 参数校验
        if (groupActivity == null || StringUtils.isEmpty(groupActivity.getActivityId())) {
            return Result.fail("活动ID不能为空");
        }

        // 2. 检查活动是否存在
        GroupActivity activity = groupActivityMapper.selectById(groupActivity.getActivityId());
        if (activity == null) {
            return Result.fail("活动不存在");
        }

        // 3. 检查是否存在拼团记录（仅允许修改未开始的活动）
        if (activity.getActivityStatus().equals("未开始")) {
            LambdaQueryWrapper<GroupRecord> queryWrapper = Wrappers.<GroupRecord>lambdaQuery()
                    .eq(GroupRecord::getActivityId, groupActivity.getActivityId());
            long recordCount = groupRecordMapper.selectCount(queryWrapper);

            if (recordCount > 0) {
                return Result.fail("活动已开始且存在拼团记录，无法修改");
            }
        }

        // 4. 检查活动名称是否重复（排除自身）
        LambdaQueryWrapper<GroupActivity> nameQuery = Wrappers.<GroupActivity>lambdaQuery()
                .eq(GroupActivity::getActivityName, groupActivity.getActivityName())
                .ne(GroupActivity::getActivityId, groupActivity.getActivityId());
        GroupActivity duplicateActivity = groupActivityMapper.selectOne(nameQuery);

        if (duplicateActivity != null) {
            return Result.fail("活动名称已存在");
        }

        // 5. 更新活动信息
        GroupActivity updateActivity = new GroupActivity();
        BeanUtils.copyProperties(groupActivity, updateActivity);
        updateActivity.setUpdateTime(LocalDateTime.now());

        int result = groupActivityMapper.updateById(updateActivity);

        if (result > 0) {
            return Result.ok("活动修改成功");
        } else {
            return Result.fail("活动修改失败");
        }
    }
}
